package york.Game.Unit;

import java.awt.Graphics;
import java.awt.Point;

import york.Game.CommandListener;
import york.Game.Command_Types;
import york.Game.Vector2D;
import york.Game.Painting.PAINTING_METHODS;
import york.Game.Painting.Painter;
import york.Game.States.STATES;
import york.Game.States.StateUser;
import york.Game.Steering.*;
import york.Game.Steering.BehaviorTypes.*;

public class SmartUnit extends Unit implements StateUser, CommandListener {
	
	STATES PreviousState;
	STATES CurrentState;
	/*
	 * CurrentBehavior will hold a specific sub class of Steering behavior
	 * with a flag that tells it how to typecast and use it.
	 */
	SteeringBehavior currentBehavior;
	SmartUnitGroup myGroup;
	Vector2D destination;
	PAINTING_METHODS MyPaintMethod;
	UNIT_TYPES MyType;
	
	public SmartUnit() {
		CurrentState = STATES.WANDER;
		PreviousState = CurrentState;
		currentBehavior = new Wander(10,10,300);
		myGroup = null;
		destination = null;
		MyPaintMethod = PAINTING_METHODS.EMPTY_OVAL;
	}
	
	public SmartUnit(int a_Arg) {
		CurrentState = STATES.WANDER;
		PreviousState = CurrentState;
		currentBehavior = null;
		myGroup = null;
		destination = null;
		MyPaintMethod = PAINTING_METHODS.EMPTY_OVAL;
	}

	public void setPaintMethod(PAINTING_METHODS a_Method) {
		MyPaintMethod = a_Method;
	}
	
	public void setDest(Point a_Dest) {
		destination = new Vector2D(a_Dest);
	}
	
	public void setDest(Vector2D a_Dest) {
		destination = a_Dest;
	}

	public void SetState(STATES NewState) {
		// TODO Auto-generated method stub
		
	}

	public STATES GetCurrentState() {
		// TODO Auto-generated method stub
		return null;
	}

	public STATES GetPreviousState() {
		// TODO Auto-generated method stub
		return null;
	}

	public void Update(double dt) {
		// TODO Auto-generated method stub
		//Do state update logic
		
		//Temporary for movement testing
		Move(dt);
		
	}
	
	public void Move(double dt) {
		if(destination != null) {
			boolean atDest = false;
			Vector2D TempVec = new Vector2D();
			
			TempVec.x = destination.x - getPosition().x;
			if(Math.abs(TempVec.x) <= 1) atDest = true;
			else atDest = false;
			
			TempVec.y = destination.y - getPosition().y;
			
			if(atDest && Math.abs(TempVec.y) <= 1)
				destination = null;
			
			if(destination != null) {
				TempVec.normalize();
				getPosition().x += TempVec.x;
				getPosition().y += TempVec.y;
			}
		}
	}
	
	public void Paint(Graphics G) {
		// TODO Auto-generated method stub
		G.setColor(color);
		Painter.Paint(G,getPosition(),(int)getSize(),MyPaintMethod);
		if(currentBehavior != null)
			currentBehavior.DebugTarget.Paint(G);
	}
	
	public void UpdateAI(double dt) {
		// TODO Auto-generated method stub
		if(MyType != UNIT_TYPES.PRIORITY && currentBehavior != null)
			currentBehavior.doWork(this,dt);
	}
	
	public void MakePriority(boolean make) {
		if(make) {
			MyType = UNIT_TYPES.PRIORITY;
			setPaintMethod(PAINTING_METHODS.FILLED_OVAL);	
		}
		else {
			MyType = UNIT_TYPES.PREDATOR;
			setPaintMethod(PAINTING_METHODS.EMPTY_OVAL);
		}
	}

	
	public void UpdateAI_Group(double dt) {
		// TODO Auto-generated method stub
		if(currentBehavior != null)
			currentBehavior.doWork(this,dt);
	}

	
	
	public boolean Dead() {
		// TODO Auto-generated method stub
		return false;
	}



	public void LeaveGroup() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void TranslateCommands() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void ReceiveCommands(Object NewCommand, Command_Types Flag) {
		// TODO Auto-generated method stub
		
	}

	public Vector2D heading(double dt) {
		Vector2D head;
		if(destination != null) head = destination;
		else head = new Vector2D(getPosition().x+5,getPosition().y);
		head.subtract(getPosition());
		if(dt > .0000001)
			head.divide(dt);
		else head.divide(.001);
		head.normalize();
		return head;
	}


	
		
}
